﻿using ElevateAVIMotion.Model;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Data;
using HalconDotNet;
using ViewROI;
using SXJLibrary;
using Microsoft.Win32;
using DALSA.SaperaLT.SapClassBasic;
using System.IO;

namespace ElevateAVIMotion.ViewModel
{
    class MainWindowViewModel: NotificationObject
    {
        #region 属性绑定
        private double xPos;

        public double XPos
        {
            get { return xPos; }
            set
            {
                xPos = value;
                this.RaisePropertyChanged("XPos");
            }
        }
        private double yPos;

        public double YPos
        {
            get { return yPos; }
            set
            {
                yPos = value;
                this.RaisePropertyChanged("YPos");
            }
        }
        private DateTime currentDateTime;

        public DateTime CurrentDateTime
        {
            get { return currentDateTime; }
            set
            {
                currentDateTime = value;
                this.RaisePropertyChanged("CurrentDateTime");
            }
        }
        private bool aLARM1;

        public bool ALARM1
        {
            get { return aLARM1; }
            set
            {
                aLARM1 = value;
                this.RaisePropertyChanged("ALARM1");
            }
        }
        private bool aLARM2;

        public bool ALARM2
        {
            get { return aLARM2; }
            set
            {
                aLARM2 = value;
                this.RaisePropertyChanged("ALARM2");
            }
        }
        private string manualPageVisibility;

        public string ManualPageVisibility
        {
            get { return manualPageVisibility; }
            set
            {
                manualPageVisibility = value;
                this.RaisePropertyChanged("ManualPageVisibility");
            }
        }
        private string editPageVisibility;

        public string EditPageVisibility
        {
            get { return editPageVisibility; }
            set
            {
                editPageVisibility = value;
                this.RaisePropertyChanged("EditPageVisibility");
            }
        }
        private string displayPageVisibility;

        public string DisplayPageVisibility
        {
            get { return displayPageVisibility; }
            set
            {
                displayPageVisibility = value;
                this.RaisePropertyChanged("DisplayPageVisibility");
            }
        }
        private ProductNumPropertyViewModel productNumPropertyModel;

        public ProductNumPropertyViewModel ProductNumPropertyModel
        {
            get { return productNumPropertyModel; }
            set
            {
                productNumPropertyModel = value;
                this.RaisePropertyChanged("ProductNumPropertyModel");
            }
        }
        private string propertyGroupBoxVisibility;

        public string PropertyGroupBoxVisibility
        {
            get { return propertyGroupBoxVisibility; }
            set
            {
                propertyGroupBoxVisibility = value;
                this.RaisePropertyChanged("PropertyGroupBoxVisibility");
            }
        }
        private string propertyConfirmButtonVisibility;

        public string PropertyConfirmButtonVisibility
        {
            get { return propertyConfirmButtonVisibility; }
            set
            {
                propertyConfirmButtonVisibility = value;
                this.RaisePropertyChanged("PropertyConfirmButtonVisibility");
            }
        }
        private string propertyUpdateButtonVisibility;

        public string PropertyUpdateButtonVisibility
        {
            get { return propertyUpdateButtonVisibility; }
            set
            {
                propertyUpdateButtonVisibility = value;
                this.RaisePropertyChanged("PropertyUpdateButtonVisibility");
            }
        }
        private ObservableCollection<ProductNumViewModel> productDataList;

        public ObservableCollection<ProductNumViewModel> ProductDataList
        {
            get { return productDataList; }
            set
            {
                productDataList = value;
                this.RaisePropertyChanged("ProductDataList");
            }
        }
        private ProductNumViewModel productDataListSelectedItem;

        public ProductNumViewModel ProductDataListSelectedItem
        {
            get { return productDataListSelectedItem; }
            set
            {
                productDataListSelectedItem = value;
                this.RaisePropertyChanged("ProductDataListSelectedItem");
            }
        }
        private bool productDataListIsEnabled;

        public bool ProductDataListIsEnabled
        {
            get { return productDataListIsEnabled; }
            set
            {
                productDataListIsEnabled = value;
                this.RaisePropertyChanged("ProductDataListIsEnabled");
            }
        }
        private string currentProductNum;

        public string CurrentProductNum
        {
            get { return currentProductNum; }
            set
            {
                currentProductNum = value;
                this.RaisePropertyChanged("CurrentProductNum");
            }
        }
        private ObservableCollection<PositionDataViewModel> positionDataList;

        public ObservableCollection<PositionDataViewModel> PositionDataList
        {
            get { return positionDataList; }
            set
            {
                positionDataList = value;
                this.RaisePropertyChanged("PositionDataList");
            }
        }
        private bool savePositionButtonIsEnabled;

        public bool SavePositionButtonIsEnabled
        {
            get { return savePositionButtonIsEnabled; }
            set
            {
                savePositionButtonIsEnabled = value;
                this.RaisePropertyChanged("SavePositionButtonIsEnabled");
            }
        }
        private PositionDataViewModel positionDataListComboBoxSelectedItem;

        public PositionDataViewModel PositionDataListComboBoxSelectedItem
        {
            get { return positionDataListComboBoxSelectedItem; }
            set
            {
                positionDataListComboBoxSelectedItem = value;
                this.RaisePropertyChanged("PositionDataListComboBoxSelectedItem");
            }
        }
        private bool showInputPositionNameWindow;

        public bool ShowInputPositionNameWindow
        {
            get { return showInputPositionNameWindow; }
            set
            {
                showInputPositionNameWindow = value;
                this.RaisePropertyChanged("ShowInputPositionNameWindow");
            }
        }
        private int inputPositionNameWindow_PositionId;

        public int InputPositionNameWindow_PositionId
        {
            get { return inputPositionNameWindow_PositionId; }
            set
            {
                inputPositionNameWindow_PositionId = value;
                this.RaisePropertyChanged("InputPositionNameWindow_PositionId");
            }
        }
        private string inputPositionNameWindow_PositionName;

        public string InputPositionNameWindow_PositionName
        {
            get { return inputPositionNameWindow_PositionName; }
            set
            {
                inputPositionNameWindow_PositionName = value;
                this.RaisePropertyChanged("InputPositionNameWindow_PositionName");
            }
        }
        private string inputPositionNameWindow_PositionRemark;

        public string InputPositionNameWindow_PositionRemark
        {
            get { return inputPositionNameWindow_PositionRemark; }
            set
            {
                inputPositionNameWindow_PositionRemark = value;
                this.RaisePropertyChanged("InputPositionNameWindow_PositionRemark");
            }
        }
        private bool quitInputPositionNameWindow;

        public bool QuitInputPositionNameWindow
        {
            get { return quitInputPositionNameWindow; }
            set
            {
                quitInputPositionNameWindow = value;
                this.RaisePropertyChanged("QuitInputPositionNameWindow");
            }
        }
        private int runSpeed;

        public int RunSpeed
        {
            get { return runSpeed; }
            set
            {
                runSpeed = value;
                this.RaisePropertyChanged("RunSpeed");
            }
        }
        private int debugSpeed;

        public int DebugSpeed
        {
            get { return debugSpeed; }
            set
            {
                debugSpeed = value;
                this.RaisePropertyChanged("DebugSpeed");
            }
        }
        private HImage cameraIamge;

        public HImage CameraIamge
        {
            get { return cameraIamge; }
            set
            {
                cameraIamge = value;
                this.RaisePropertyChanged("CameraIamge");
            }
        }
        private bool cameraRepaint;

        public bool CameraRepaint
        {
            get { return cameraRepaint; }
            set
            {
                cameraRepaint = value;
                this.RaisePropertyChanged("CameraRepaint");
            }
        }
        private ObservableCollection<ROI> cameraROIList;

        public ObservableCollection<ROI> CameraROIList
        {
            get { return cameraROIList; }
            set
            {
                cameraROIList = value;
                this.RaisePropertyChanged("CameraROIList");
            }
        }
        private HObject cameraAppendHObject;

        public HObject CameraAppendHObject
        {
            get { return cameraAppendHObject; }
            set
            {
                cameraAppendHObject = value;
                this.RaisePropertyChanged("CameraAppendHObject");
            }
        }
        private Tuple<string, object> cameraGCStyle;

        public Tuple<string, object> CameraGCStyle
        {
            get { return cameraGCStyle; }
            set
            {
                cameraGCStyle = value;
                this.RaisePropertyChanged("CameraGCStyle");
            }
        }
        private HImage cameraIamge2;

        public HImage CameraIamge2
        {
            get { return cameraIamge2; }
            set
            {
                cameraIamge2 = value;
                this.RaisePropertyChanged("CameraIamge2");
            }
        }
        private bool cameraRepaint2;

        public bool CameraRepaint2
        {
            get { return cameraRepaint2; }
            set
            {
                cameraRepaint2 = value;
                this.RaisePropertyChanged("CameraRepaint2");
            }
        }
        private ObservableCollection<ROI> cameraROIList2;

        public ObservableCollection<ROI> CameraROIList2
        {
            get { return cameraROIList2; }
            set
            {
                cameraROIList2 = value;
                this.RaisePropertyChanged("CameraROIList2");
            }
        }
        private HObject cameraAppendHObject2;

        public HObject CameraAppendHObject2
        {
            get { return cameraAppendHObject2; }
            set
            {
                cameraAppendHObject2 = value;
                this.RaisePropertyChanged("CameraAppendHObject2");
            }
        }
        private Tuple<string, object> cameraGCStyle2;

        public Tuple<string, object> CameraGCStyle2
        {
            get { return cameraGCStyle2; }
            set
            {
                cameraGCStyle2 = value;
                this.RaisePropertyChanged("CameraGCStyle2");
            }
        }
        private HImage cameraIamge3;

        public HImage CameraIamge3
        {
            get { return cameraIamge3; }
            set
            {
                cameraIamge3 = value;
                this.RaisePropertyChanged("CameraIamge3");
            }
        }
        private bool cameraRepaint3;

        public bool CameraRepaint3
        {
            get { return cameraRepaint3; }
            set
            {
                cameraRepaint3 = value;
                this.RaisePropertyChanged("CameraRepaint3");
            }
        }
        private ObservableCollection<ROI> cameraROIList3;

        public ObservableCollection<ROI> CameraROIList3
        {
            get { return cameraROIList3; }
            set
            {
                cameraROIList3 = value;
                this.RaisePropertyChanged("CameraROIList3");
            }
        }
        private HObject cameraAppendHObject3;

        public HObject CameraAppendHObject3
        {
            get { return cameraAppendHObject3; }
            set
            {
                cameraAppendHObject3 = value;
                this.RaisePropertyChanged("CameraAppendHObject3");
            }
        }
        private Tuple<string, object> cameraGCStyle3;

        public Tuple<string, object> CameraGCStyle3
        {
            get { return cameraGCStyle3; }
            set
            {
                cameraGCStyle3 = value;
                this.RaisePropertyChanged("CameraGCStyle3");
            }
        }
        private string logPageVisibility;

        public string LogPageVisibility
        {
            get { return logPageVisibility; }
            set
            {
                logPageVisibility = value;
                this.RaisePropertyChanged("LogPageVisibility");
            }
        }
        private string messageStr;

        public string MessageStr
        {
            get { return messageStr; }
            set
            {
                messageStr = value;
                this.RaisePropertyChanged("MessageStr");
            }
        }
        private bool statusCamera;

        public bool StatusCamera
        {
            get { return statusCamera; }
            set
            {
                statusCamera = value;
                this.RaisePropertyChanged("StatusCamera");
            }
        }
        private bool statusPLC;

        public bool StatusPLC
        {
            get { return statusPLC; }
            set
            {
                statusPLC = value;
                this.RaisePropertyChanged("StatusPLC");
            }
        }

        #endregion
        #region 方法绑定
        public DelegateCommand AppLoadedEventCommand { get; set; }
        public DelegateCommand AppClosedEventCommand { get; set; }
        public DelegateCommand<object> PreviewMouseUpCommand { get; set; }
        public DelegateCommand<object> PreviewMouseDownCommand { get; set; }
        public DelegateCommand<object> MenuActionCommand { get; set; }
        public DelegateCommand<object> PropertyWindowCommand { get; set; }
        public DelegateCommand SavePositionValueCommand { get; set; }
        public DelegateCommand CellEditEndingEventCommand { get; set; }
        public DelegateCommand<object> ManualButtonCommand { get; set; }
        public DelegateCommand TeachPositionConfirmButtonCommand { get; set; }
        public DelegateCommand SaveSpeedCommand { get; set; }
        public DelegateCommand<object> CameraOperateButtonCommand { get; set; }
        #endregion
        #region 变量
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        SQLite sqlite = new SQLite();
        private string iniParameterPath = System.Environment.CurrentDirectory + "\\Parameter.ini";
        XinjePLCModbusRTU plc; bool camDir = false;
        #region Dalsa
        SapAcquisition m_Acquisition = null;
        SapAcqDevice m_Camera = null;
        SapBuffer m_Buffer = null;
        SapBuffer m_ExBuffer = null;
        SapAcqToBuf m_Xfer = null;

        int Width = 0;
        int Height = 0;

        #endregion
        #endregion
        #region 构造函数
        public MainWindowViewModel()
        {
            #region 属性初始化
            ManualPageVisibility = "Collapsed";
            
            EditPageVisibility = "Collapsed";
            
            DisplayPageVisibility = "Visible";

            LogPageVisibility = "Collapsed";
            PropertyGroupBoxVisibility = "Collapsed";

            MessageStr = "";
            ProductDataList = new ObservableCollection<ProductNumViewModel>();
            ProductDataListIsEnabled = true;
            PositionDataList = new ObservableCollection<PositionDataViewModel>();
            SavePositionButtonIsEnabled = false;

            CameraROIList = new ObservableCollection<ROI>();
            CameraROIList2 = new ObservableCollection<ROI>();

            #endregion
            #region 方法绑定
            AppLoadedEventCommand = new DelegateCommand(new Action(this.AppLoadedEventCommandExecute));
            AppClosedEventCommand = new DelegateCommand(new Action(this.AppClosedEventCommandExecute));
            PreviewMouseUpCommand = new DelegateCommand<object>(new Action<object>(this.PreviewMouseUpCommandExecute));
            PreviewMouseDownCommand = new DelegateCommand<object>(new Action<object>(this.PreviewMouseDownCommandExecute));
            MenuActionCommand = new DelegateCommand<object>(new Action<object>(this.MenuActionCommandExecute));
            PropertyWindowCommand = new DelegateCommand<object>(new Action<object>(this.PropertyWindowCommandExecute));
            SavePositionValueCommand = new DelegateCommand(new Action(this.SavePositionValueCommandExecute));
            CellEditEndingEventCommand = new DelegateCommand(new Action(this.CellEditEndingEventCommandExecute));
            ManualButtonCommand = new DelegateCommand<object>(new Action<object>(this.ManualButtonCommandExecute));
            TeachPositionConfirmButtonCommand = new DelegateCommand(new Action(this.TeachPositionConfirmButtonCommandExecute));
            SaveSpeedCommand = new DelegateCommand(new Action(this.SaveSpeedCommandExecute));
            CameraOperateButtonCommand = new DelegateCommand<object>(new Action<object>(this.CameraOperateButtonCommandExecute));
            #endregion
            #region 变量初始化
            string comPort = DXH.Ini.DXHIni.ContentReader("PLC", "COM", "COM1", iniParameterPath);
            plc = new XinjePLCModbusRTU(comPort);
            plc.ConnectStateChanged += Plc_ConnectStateChanged;
            #endregion
            upDataUI();
            Run();
        }


        #endregion
        #region 方法绑定函数
        private void AppLoadedEventCommandExecute()
        {
            try
            {
                if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                {
                    string sql = "SELECT * FROM ProductNum ORDER BY Id ASC";
                    DataSet ds = sqlite.ExecuteQuery(sql);
                    
                    DataTable dt = ds.Tables[0];
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        ProductDataList.Add(new ProductNumViewModel
                        {
                            Id = (int)(long)dt.Rows[i]["Id"],
                            Name = (string)dt.Rows[i]["Name"],
                            Remark = (string)dt.Rows[i]["Remark"],
                        });
                        if ((int)(long)dt.Rows[i]["Selected"] == 1)
                        {
                            CurrentProductNum = (string)dt.Rows[i]["Name"];
                        }
                    }

                    
                    sqlite.Disconnect();
                }
                else
                {
                    logger.Info("数据库连接失败");
                    HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                readAllPositionFromSqlite(CurrentProductNum);

                bool rst = DalsaInit();
                StatusCamera = rst;
                if (rst)
                {
                    addMessage("相机打开成功");
                }
                else
                {
                    addMessage("相机打开失败");
                }
                plc.Start();
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }
        private void AppClosedEventCommandExecute()
        {
            try
            {
                m_Xfer.Abort();
                Destroy();
            }
            catch { }
        }
        private void PropertyWindowCommandExecute(object obj)
        {
            switch (obj.ToString())
            {
                case "0"://添加
                    ProductNumPropertyModel = new ProductNumPropertyViewModel
                    {
                        Name = "",
                        Remark = ""
                    };
                    PropertyConfirmButtonVisibility = "Visible";
                    PropertyUpdateButtonVisibility = "Collapsed";
                    PropertyGroupBoxVisibility = "Visible";
                    break;
                case "1"://编辑
                    PropertyGroupBoxVisibility = "Collapsed";
                    if (ProductDataListSelectedItem != null)
                    {
                        ProductNumPropertyModel = new ProductNumPropertyViewModel
                        {
                            Name = ProductDataListSelectedItem.Name,
                            Remark = ProductDataListSelectedItem.Remark
                        };
                        PropertyConfirmButtonVisibility = "Collapsed";
                        PropertyUpdateButtonVisibility = "Visible";
                        PropertyGroupBoxVisibility = "Visible";
                        ProductDataListIsEnabled = false;
                    }
                    else
                    {
                        logger.Info("未选择任何料号");
                        HandyControl.Controls.MessageBox.Show("未选择任何料号", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    break;
                case "2"://删除
                    PropertyGroupBoxVisibility = "Collapsed";
                    if (ProductDataListSelectedItem != null)
                    {
                        if (HandyControl.Controls.MessageBox.Show($"你确定删除料号:{ProductDataListSelectedItem.Name} 吗？", "确认", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
                        {
                            try
                            {
                                if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                                {
                                    string sql = $"DROP TABLE IF EXISTS Position_{ProductDataListSelectedItem.Id}";
                                    sqlite.ExecuteNonQuery(sql);
                                    sql = $"DELETE FROM ProductNum WHERE Id = {ProductDataListSelectedItem.Id}";
                                    sqlite.ExecuteNonQuery(sql);
                                    sql = $"DROP TABLE IF EXISTS Position_{ProductDataListSelectedItem.Id}";
                                    sqlite.ExecuteNonQuery(sql);
                                    ProductDataList.Clear();
                                    sql = "SELECT * FROM ProductNum ORDER BY Id ASC";
                                    DataSet ds = sqlite.ExecuteQuery(sql);
                                    
                                    sqlite.Disconnect();
                                    DataTable dt = ds.Tables[0];
                                    for (int i = 0; i < dt.Rows.Count; i++)
                                    {
                                        ProductDataList.Add(new ProductNumViewModel
                                        {
                                            Id = (int)(long)dt.Rows[i]["Id"],
                                            Name = (string)dt.Rows[i]["Name"],
                                            Remark = (string)dt.Rows[i]["Remark"],
                                        });
                                    }

                                }
                                else
                                {
                                    logger.Info("数据库连接失败");
                                    HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                                }
                            }
                            catch (Exception ex)
                            {
                                logger.Error(ex);
                                HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                        }
                    }
                    else
                    {
                        logger.Info("未选择任何料号");
                        HandyControl.Controls.MessageBox.Show("未选择任何料号", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }               
                    break;
                case "3"://确定
                    try
                    {
                        if (ProductNumPropertyModel.Name != "")
                        {
                            if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                            {
                                string sql = $"INSERT INTO ProductNum (Name, Remark,Selected) VALUES ('{ProductNumPropertyModel.Name}', '{ProductNumPropertyModel.Remark}',0)";
                                sqlite.ExecuteNonQuery(sql);
                                ProductDataList.Clear();
                                sql = "SELECT * FROM ProductNum ORDER BY Id ASC";
                                DataSet ds = sqlite.ExecuteQuery(sql);
                                
                                DataTable dt = ds.Tables[0];
                                for (int i = 0; i < dt.Rows.Count; i++)
                                {
                                    ProductDataList.Add(new ProductNumViewModel
                                    {
                                        Id = (int)(long)dt.Rows[i]["Id"],
                                        Name = (string)dt.Rows[i]["Name"],
                                        Remark = (string)dt.Rows[i]["Remark"],
                                    });
                                }
                                DataRow[] drs = dt.Select($"Name = '{ProductNumPropertyModel.Name}'");
                                sql = $"CREATE TABLE IF NOT EXISTS [Position_{drs[0]["Id"]}] ( [Id] INTEGER NOT NULL, [X] REAL NOT NULL, [Y] REAL NOT NULL, [Name] TEXT,[Remark] TEXT, CONSTRAINT[PK_Position_{drs[0]["Id"]}] PRIMARY KEY([Id]))";
                                sqlite.ExecuteNonQuery(sql);
                                for (int i = 0; i < 10; i++)
                                {
                                    sql = $"INSERT INTO Position_{drs[0]["Id"]} (X, Y) VALUES (0, 0)";
                                    sqlite.ExecuteNonQuery(sql);
                                }
                                sqlite.Disconnect();
                            }
                            else
                            {
                                logger.Info("数据库连接失败");
                                HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            }
                        }
                        else
                        {
                            logger.Info("未选择任何料号");
                            HandyControl.Controls.MessageBox.Show("未选择任何料号", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex);
                        HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    PropertyGroupBoxVisibility = "Collapsed";
                    break;
                case "4"://更新
                    try
                    {
                        if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                        {
                            string sql = $"UPDATE ProductNum SET Name = '{ProductNumPropertyModel.Name}', Remark = '{ProductNumPropertyModel.Remark}' WHERE Id = {ProductDataListSelectedItem.Id}";
                            sqlite.ExecuteNonQuery(sql);
                            ProductDataList.Clear();
                            sql = "SELECT * FROM ProductNum ORDER BY Id ASC";
                            DataSet ds = sqlite.ExecuteQuery(sql);
                            sqlite.Disconnect();
                            DataTable dt = ds.Tables[0];
                            for (int i = 0; i < dt.Rows.Count; i++)
                            {
                                ProductDataList.Add(new ProductNumViewModel
                                {
                                    Id = (int)(long)dt.Rows[i]["Id"],
                                    Name = (string)dt.Rows[i]["Name"],
                                    Remark = (string)dt.Rows[i]["Remark"],
                                });
                            }

                        }
                        else
                        {
                            logger.Info("数据库连接失败");
                            HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex);
                        HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    ProductDataListIsEnabled = true;
                    PropertyGroupBoxVisibility = "Collapsed";
                    break;
                case "5"://取消
                    PropertyGroupBoxVisibility = "Collapsed";
                    ProductDataListIsEnabled = true;
                    break;
                case "6":
                    if (ProductDataListSelectedItem != null)
                    {
                        if (HandyControl.Controls.MessageBox.Show($"你确定更换料号吗？", "确认", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
                        {
                            try
                            {
                                if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                                {
                                    string sql = $"UPDATE ProductNum SET Selected = 0";
                                    sqlite.ExecuteNonQuery(sql);
                                    sql = $"UPDATE ProductNum SET Selected = 1 WHERE Id = {ProductDataListSelectedItem.Id}";
                                    sqlite.ExecuteNonQuery(sql);
                                    sqlite.Disconnect();
                                    CurrentProductNum = ProductDataListSelectedItem.Name;
                                    readAllPositionFromSqlite(CurrentProductNum);
                                }
                                else
                                {
                                    logger.Info("数据库连接失败");
                                    HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                                }
                            }
                            catch (Exception ex)
                            {
                                logger.Error(ex);
                                HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            }

                        }
                    }
                    else
                    {
                        logger.Info("未选择任何料号");
                        HandyControl.Controls.MessageBox.Show("未选择任何料号", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    break;
                default:
                    break;
            }
        }
        private void PreviewMouseUpCommandExecute(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    plc.SetM("M62", false);
                    break;
                case "1":
                    plc.SetM("M63", false);
                    break;
                case "2":
                    plc.SetM("M60", false);
                    break;
                case "3":
                    plc.SetM("M61", false);
                    break;
                case "100":
                    plc.SetM("M55", false);
                    break;
                case "101":
                    plc.SetM("M65", false);
                    break;
                default:
                    break;
            }
        }
        private void PreviewMouseDownCommandExecute(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    plc.SetM("M62",true);
                    break;
                case "1":
                    plc.SetM("M63", true);
                    break;
                case "2":
                    plc.SetM("M60", true);
                    break;
                case "3":
                    plc.SetM("M61", true);
                    break;
                case "100":
                    plc.SetM("M55", true);
                    break;
                case "101":
                    plc.SetM("M65", true);
                    break;
                default:
                    break;
            }
        }
        private void MenuActionCommandExecute(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    ManualPageVisibility = "Visible";
                    EditPageVisibility = "Collapsed";
                    DisplayPageVisibility = "Collapsed";
                    LogPageVisibility = "Collapsed";
                    break;
                case "1":
                    ManualPageVisibility = "Collapsed";
                    EditPageVisibility = "Visible";
                    DisplayPageVisibility = "Collapsed";
                    LogPageVisibility = "Collapsed";
                    break;
                case "2":
                    ManualPageVisibility = "Collapsed";
                    EditPageVisibility = "Collapsed";
                    DisplayPageVisibility = "Visible";
                    LogPageVisibility = "Collapsed";
                    break;
                case "3":
                    ManualPageVisibility = "Collapsed";
                    EditPageVisibility = "Collapsed";
                    DisplayPageVisibility = "Collapsed";
                    LogPageVisibility = "Visible";
                    break;
                default:
                    break;
            }
        }
        private void SavePositionValueCommandExecute()
        {
            if (HandyControl.Controls.MessageBox.Show($"你确定保存点位吗？", "确认", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
            {
                try
                {
                    if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                    {
                        string sql = $"SELECT * FROM ProductNum WHERE NAME = '{CurrentProductNum}'";
                        DataSet ds = sqlite.ExecuteQuery(sql);
                        DataTable dt = ds.Tables[0];
                        int currentId = 0;
                        if (dt.Rows.Count > 0)
                        {
                            currentId = (int)(long)dt.Rows[0]["Id"];

                            foreach (PositionDataViewModel item in PositionDataList)
                            {
                                sql = $"UPDATE Position_{currentId} SET Name = '{item.Name}',X = {item.X},Y = {item.Y},Remark = '{item.Remark}' WHERE Id = {item.Id}";
                                sqlite.ExecuteNonQuery(sql);
                                plc.WriteW("D" + (4206 + (item.Id - 1) * 4).ToString(), (int)(item.X * 100));
                                plc.WriteW("D" + (4208 + (item.Id - 1) * 4).ToString(), (int)(item.Y * 100));
                            }
                        }
                        sqlite.Disconnect();
                        SavePositionButtonIsEnabled = false;
                    }
                    else
                    {
                        logger.Info("数据库连接失败");
                        HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                catch (Exception ex)
                {
                    logger.Error(ex);
                    HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
                

        }
        private void CellEditEndingEventCommandExecute()
        {
            SavePositionButtonIsEnabled = true;
        }
        private void TeachPositionConfirmButtonCommandExecute()
        {
            QuitInputPositionNameWindow = !QuitInputPositionNameWindow;
            PositionDataListComboBoxSelectedItem.Name = InputPositionNameWindow_PositionName;
            PositionDataListComboBoxSelectedItem.Remark = InputPositionNameWindow_PositionRemark;
            PositionDataListComboBoxSelectedItem.X = XPos;
            PositionDataListComboBoxSelectedItem.Y = YPos;
            SavePositionButtonIsEnabled = true;
        }
        private void ManualButtonCommandExecute(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    if (PositionDataListComboBoxSelectedItem != null)
                    {
                        InputPositionNameWindow_PositionId = PositionDataListComboBoxSelectedItem.Id;
                        InputPositionNameWindow_PositionName = PositionDataListComboBoxSelectedItem.Name;
                        InputPositionNameWindow_PositionRemark = PositionDataListComboBoxSelectedItem.Remark;
                        ShowInputPositionNameWindow = !ShowInputPositionNameWindow;
                    }
                    else
                    {
                        HandyControl.Controls.MessageBox.Show("未选择任何点", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }                   
                    break;
                case "1":
                    if (PositionDataListComboBoxSelectedItem != null)
                    {
                        if (HandyControl.Controls.MessageBox.Show($"你确定要运动到点 {PositionDataListComboBoxSelectedItem.Id} 吗？", "确认", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.Yes)
                        {
                            plc.WriteW("D4204", DebugSpeed);//写调试速度
                            plc.WriteD("D10",(short)PositionDataListComboBoxSelectedItem.Id);//写索引需要
                            plc.SetM("M64",true);//开始运动
                        }
                    }
                    else
                    {
                        HandyControl.Controls.MessageBox.Show("未选择任何点", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    break;
                default:
                    break;
            }
        }
        private void SaveSpeedCommandExecute()
        {
            try
            {
                if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                {
                    string stm = $"UPDATE ProductNum SET RunSpeed = {RunSpeed},DebugSpeed = {DebugSpeed} WHERE NAME = '{CurrentProductNum}'";
                    sqlite.ExecuteNonQuery(stm);
                    plc.WriteW("D4200", RunSpeed);//写运行速度
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void CameraOperateButtonCommandExecute(object obj)
        {
            switch (obj.ToString())
            {
                case "0":
                    try
                    {
                        OpenFileDialog openFileDialog = new OpenFileDialog();
                        openFileDialog.Filter = "Image Files (*.bmp;*.png;*.jpg)|*.bmp;*.png;*.jpg";
                        if (openFileDialog.ShowDialog() == true)
                        {
                            HObject img; 
                            HOperatorSet.ReadImage(out img,openFileDialog.FileName);
                            CameraIamge3 = new HImage(img);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex);
                        HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    break;

                default:
                    break;
            }
        }
        #endregion
        #region 自定义函数
        private void Plc_ConnectStateChanged(object sender, bool e)
        {
            StatusPLC = e;
        }
        private void readAllPositionFromSqlite(string ProductNum)
        {
            try
            {
                if (sqlite.Connect("DataSource=AVISQLite.sqlite;Version=3"))
                {
                    string sql = $"SELECT * FROM ProductNum WHERE NAME = '{ProductNum}'";
                    DataSet ds = sqlite.ExecuteQuery(sql);

                    DataTable dt = ds.Tables[0];
                    int currentId = 0;
                    if (dt.Rows.Count > 0)
                    {
                        currentId = (int)(long)dt.Rows[0]["Id"];
                        sql = $"SELECT * FROM Position_{currentId}";
                        DataSet ds1 = sqlite.ExecuteQuery(sql);
                        DataTable dt1 = ds1.Tables[0];
                        PositionDataList.Clear();
                        for (int i = 0; i < dt1.Rows.Count; i++)
                        {
                            PositionDataList.Add(
                                new PositionDataViewModel
                                {
                                    Id = (int)(long)dt1.Rows[i]["Id"],
                                    Name = dt1.Rows[i]["Name"] != DBNull.Value ? (string)dt1.Rows[i]["Name"] : "",
                                    X = (double)dt1.Rows[i]["X"],
                                    Y = (double)dt1.Rows[i]["Y"],
                                    Remark = dt1.Rows[i]["Remark"] != DBNull.Value ? (string)dt1.Rows[i]["Remark"] : ""
                                }
                                ) ;
                            plc.WriteW("D" + (4206 + i * 4).ToString(), (int)((double)dt1.Rows[i]["X"] * 100));
                            plc.WriteW("D" + (4208 + i * 4).ToString(), (int)((double)dt1.Rows[i]["Y"] * 100));
                        }
                        RunSpeed = dt.Rows[0]["RunSpeed"] == DBNull.Value ? 10000 : (int)(long)dt.Rows[0]["RunSpeed"];
                        DebugSpeed = dt.Rows[0]["DebugSpeed"] == DBNull.Value ? 1000 : (int)(long)dt.Rows[0]["DebugSpeed"];
                        plc.WriteW("D4200", RunSpeed);//写运行速度
                        plc.WriteW("D4204", DebugSpeed);//写运行速度
                    }                    
                    sqlite.Disconnect();
                }
                else
                {
                    logger.Info("数据库连接失败");
                    HandyControl.Controls.MessageBox.Show("数据库连接失败", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                HandyControl.Controls.MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void addMessage(string str)
        {
            string[] s = MessageStr.Split('\n');
            if (s.Length > 1000)
            {
                MessageStr = "";
            }
            if (MessageStr != "")
            {
                MessageStr += "\n";
            }
            MessageStr += System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " " + str;
        }
        #endregion
        #region 运行Loop
        async void upDataUI()
        {
            while (true)
            {
                try
                {
                    CurrentDateTime = DateTime.Now;
                    //StatusCamera = cam1.Connected;
                }
                catch { }
                await Task.Delay(1000);
            }
        }
        async void Run()
        {
            bool m120 = false, m121 = false, m122 = false, m123 = false;
            while (true)
            {
                try
                {
                    #region 读取坐标
                    await Task.Run(()=> {
                        XPos = (double)plc.ReadW("D4022") / 100;
                        YPos = (double)plc.ReadW("D4024") / 100;
                    });
                    #endregion
                    #region 读信息
                    bool[] M120 = await Task.Run<bool[]>(() =>
                    {
                        return plc.ReadMultiM("M120", 16);
                    });
                    if (M120 != null)
                    {
                        if (m120 != M120[0])
                        {
                            if (M120[0])
                            {
                                addMessage("初始化S0");
                            }
                            m120 = M120[0];
                        }
                        if (m121 != M120[1])
                        {
                            if (M120[1])
                            {
                                addMessage("模式选择S10");
                            }
                            m121 = M120[1];
                        }
                        if (m122 != M120[2])
                        {
                            if (M120[2])
                            {
                                addMessage("调试模式S50");
                            }
                            m122 = M120[2];
                        }
                        if (m123 != M120[3])
                        {
                            if (M120[3])
                            {
                                addMessage("运行模式");
                            }
                            m123 = M120[3];
                        }
                    }
                    
                    #endregion
                    #region 运行
                    bool m100 = await Task.Run<bool>(() =>
                    {
                        return plc.ReadM("M100");
                    });
                    if (m100)
                    {
                        addMessage("触发拍照");
                        await Task.Run(() =>
                        {

                            plc.SetM("M100", false);
                            if (!m_Xfer.Grabbing)
                            {
                                m_Camera.SetFeatureValue("sensorScanDirection", "Reverse");
                                camDir = true;
                                m_Xfer.Grab();
                            }

                        });
                      
                    }

                    bool m101 = await Task.Run<bool>(() =>
                    {
                        return plc.ReadM("M101");
                    });
                    if (m101)
                    {
                        addMessage("触发拍照2");
                        await Task.Run(() =>
                        {

                            plc.SetM("M101", false);
                            if (!m_Xfer.Grabbing)
                            {
                                m_Camera.SetFeatureValue("sensorScanDirection", "Forward");
                                camDir = false;
                                m_Xfer.Grab();
                            }

                        });
                   
                    }
                    #endregion
                }
                catch { }
                await Task.Delay(100);
            }
        }
        private bool DalsaInit()
        {
            int serverCount = SapManager.GetServerCount(SapManager.ResourceType.Acq);

            if (serverCount > 0)
            {
                string m_ServerNameAcq = SapManager.GetServerName(0, SapManager.ResourceType.Acq);
                SapLocation loc = new SapLocation(m_ServerNameAcq, 1);
                m_Acquisition = new SapAcquisition(loc, Path.Combine(System.Environment.CurrentDirectory, "20210118.ccf"));
                m_Buffer = new SapBufferWithTrash(2, m_Acquisition, SapBuffer.MemoryType.Default);
                m_Xfer = new SapAcqToBuf(m_Acquisition, m_Buffer);
                m_Xfer.Pairs[0].EventType = SapXferPair.XferEventType.EndOfFrame;
                m_Xfer.XferNotify += new SapXferNotifyHandler(DalsaCallBack);
                m_Xfer.XferNotifyContext = this;

                string m_ServerNameAcqDevice = SapManager.GetServerName(0, SapManager.ResourceType.AcqDevice);
                SapLocation loc1 = new SapLocation(m_ServerNameAcqDevice, 0);
                m_Camera = new SapAcqDevice(loc1, false);


                if (m_Acquisition != null && !m_Acquisition.Initialized)
                {
                    if (m_Acquisition.Create() == false)
                    { Destroy(); return false; }
                }
                if (m_Camera != null && !m_Camera.Initialized)
                {
                    if (m_Camera.Create() == false)
                    { Destroy(); return false; }
                }
                if (m_Buffer != null && !m_Buffer.Initialized)
                {
                    if (m_Buffer.Create() == false)
                    { Destroy(); return false; }
                    m_Buffer.Clear();
                }
                if (m_Xfer != null && !m_Xfer.Initialized)
                {
                    if (m_Xfer.Create() == false)
                    { Destroy(); return false; }
                }

                Width = m_Buffer.Width;
                Height = m_Buffer.Height;
                //ImageSize = Width * Height;

                m_ExBuffer = new SapBuffer(2, Width, Height, SapFormat.RGB888, SapBuffer.MemoryType.Default);
                if (m_ExBuffer != null && !m_ExBuffer.Initialized)
                {
                    if (m_ExBuffer.Create() == false)
                    { Destroy(); return false; }
                    m_ExBuffer.Clear();
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        private void DalsaCallBack(object sender, SapXferNotifyEventArgs args)
        {
            m_ExBuffer.Copy(m_Buffer);
            IntPtr p = IntPtr.Zero;
            m_ExBuffer.GetAddress(out p);
            HObject imageRGB;
            HOperatorSet.GenImageInterleaved(out imageRGB, p, "rgb", m_ExBuffer.Width, m_ExBuffer.Height, 0, "byte", m_ExBuffer.Width, m_ExBuffer.Height, 0, 0, -1, 0);
            if (camDir)
            {
                CameraIamge = new HImage(imageRGB);
                addMessage("正向拍照完成");
            }
            else
            {
                CameraIamge2 = new HImage(imageRGB);
                addMessage("反向拍照完成");
            }


            m_Xfer.Abort();
        }

        private void Destroy()
        {
            if (m_Xfer != null && m_Xfer.Initialized)
                m_Xfer.Destroy();
            if (m_ExBuffer != null && m_ExBuffer.Initialized)
                m_ExBuffer.Destroy();
            if (m_Buffer != null && m_Buffer.Initialized)
                m_Buffer.Destroy();
            //if (m_Feature != null && m_Feature.Initialized)
            //    m_Feature.Destroy();
            if (m_Camera != null && m_Camera.Initialized)
                m_Camera.Destroy();
            if (m_Acquisition != null && m_Acquisition.Initialized)
                m_Acquisition.Destroy();
        }
        #endregion
    }
}
